﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace iLangl
{
	public class BaseAlertManager : IAlertManager
	{
		protected IAlertDAL _alertDAL = null;
		public BaseAlertManager()
		{
			_alertDAL = new BaseAlertDAL();
		}

		public virtual IAlert CreateAlert(object source)
		{
			IAlert alert = null;
			if (source == null)
				alert = new Alert(String.Empty);
			else
				alert = new Alert(source.ToString());

			alert.Id = Guid.NewGuid().ToString();
			
			return alert;
		}

		public virtual IAlert CreateAlert(object source, IList<IError> errors)
		{
			IAlert alert = CreateAlert(source);
			alert.AddErrors(errors);
			return alert;
		}


		public virtual IAlert CreateAlert(object source, Exception exception)
		{
			IAlert alert = CreateAlert(source);
			alert.AddException(exception);
			return alert;
		}

		public virtual void RaiseAlert(IAlert alert)
		{
			if (alert == null)
				return;


			_alertDAL.SaveAlert(CreateSerializedAlert(alert), null);


			foreach (IAlertNotificationProvider notificationProvider in notificationProvidors)
			{
				try
				{
					notificationProvider.Notify(alert);
				}
				catch (System.Exception ex)
				{
					throw ex;
				}
			}

			raiseException(alert);
		}

		protected virtual void raiseException(IAlert alert)
		{
			//Not raize exception if severity below high
			if ((int)alert.Severity < (int)eSeverity.High)
				return;

			if (alert.Errors != null)
			{
				ErrorsRequestContext context = new ErrorsRequestContext();
				context.SetContext(alert.Errors);
				throw new AlertException(context.GetContext().ToString());
				
			}

			
			if ((alert.Exceptions != null) && (alert.Exceptions.Count > 0))
				throw new AlertException(alert.Source, alert.Exceptions[0]);
			
		}

		public virtual void RaiseAlert(Exception ex)
		{
			if (ex is AlertException)
				return;

			IAlert alert = CreateAlert(ex.Source, ex);
			RaiseAlert(alert);

			
		}

		public virtual void AddNotificationProvider(IAlertNotificationProvider notificationProvider)
		{
			if (notificationProvider == null)
				return; 

			notificationProvidors.Add(notificationProvider);
		}


		public virtual void RemoveNotificationProvider(IAlertNotificationProvider notificationProvider)
		{
			if (notificationProvider == null)
				return; 

			notificationProvidors.Remove(notificationProvider);
		}

		private IList<IAlertNotificationProvider> _notificationProvidors;
		private IList<IAlertNotificationProvider> notificationProvidors
		{
			get
			{
				if (_notificationProvidors == null)
				{
					_notificationProvidors = new List<IAlertNotificationProvider>();
				}

				return _notificationProvidors;
			}
		}

		public virtual IAlertNotificationProvider[] NotificationProviders
		{
			get 
			{
				return notificationProvidors.ToArray();
			}
		}

		public virtual void SetAlertDAL(IAlertDAL alertDAL)
		{
			_alertDAL = alertDAL;
		}



		public ISerializedAlert CreateSerializedAlert()
		{
			return new BaseSerializedAlert();
		}

		#region IAlertManager Members


		public ISerializedAlert CreateSerializedAlert(IAlert alert)
		{
			ISerializedAlert serializedAlert = CreateSerializedAlert();
			serializedAlert.Id = alert.Id;
			serializedAlert.Created = alert.Created;
			serializedAlert.Severity = alert.Severity;
			serializedAlert.Source = alert.Source;

			AlertSerializeContext context = new AlertSerializeContext();
			context.SetContext(alert);
			serializedAlert.Content = (String)context.GetContext();

			if ((alert.Packages != null) && (alert.Packages.Count > 0))
			{
				IList<String> packageIds = new List<String>();
				foreach (IPackage package in alert.Packages)
				{
					packageIds.Add(package.Id);
				}
				serializedAlert.PackageIds = packageIds.ToArray();
			}

			return serializedAlert;
		}

		#endregion
	}
}
